import DatePicker from "components/antd-compatible/date-picker";
/**
 * Created by tanbingqin on 2020/7/6.
 */
import React, { Component, PropTypes } from "react";
import { messages, deepFullCopy, queryCurrencyPrecision, eventTrack } from 'share/common'
import { connect } from 'react-redux';
import moment from 'moment'
import requestService from 'containers/request/request.service'
import travelService from 'containers/request/travel-request/travel.service'
import baseService from 'share/base.service'
import errorMessage from 'share/errorMessage';
import 'styles/request/new-card-request.scss'
import { Button, Row, Col, Icon,  Checkbox, message, Popconfirm, Spin, Form, Tag, Popover, Table, InputNumber } from 'antd'
import Condition from 'components/condition';
const If = Condition.If;
import travelUtil from 'containers/request/travel-request/travelUtil'
import requestUtil from 'containers/request/slide/request-util'
import TravelLocation from 'containers/request/travel-request/comp/location'
const CheckboxGroup = Checkbox.Group;
import debounce from 'lodash.debounce'
const FormItem = Form.Item;
import customField from 'share/customField'
import Chooser from 'components/chooser'
import chooserData from 'share/chooserData'
import config from 'config'
const formItemLayout = {
  labelCol: {span: 6},
  wrapperCol: {span: 14},
};

class RequestItineraryForm extends Component{
  constructor(props) {
    super(props);
    this.state = {
      loading: false,
      budgetLoading: false,
      isHasAutoBudget: false, //是否调用过后台生成预算接口
      isBudgetErr: false, //生成预算是否有报错
      copyValues: [], //表单上控件值的备份，以及控件onChange额外处理的监听，这里费用表单上不想处理备份信息，只把监听装上
      isConsumerErr: false, //行程头的城市是否在对应消费商下支持
      isHasApportion: false, //是否有分摊，配置了com_budget控件且费用类型开启了分摊，则表示有分摊
      apportionList: [], //分摊列表的数据
      tableLoading: false, //分摊table的loading
      currencyCode: '', //com_budget控件上的currencyCode
      amount: null, //com_budget控件上的amount
      customFormFields: [], //把props传进来的customFormFields转换，主要处理拼装日期连选控件
    };
    this.checkedChange = debounce(this.checkedChange, 200);
  }

  componentDidMount() {
    this.initApportion();
    this.initCopyValues();
    this.initFields();
    this.initAmount();
  }

  componentWillReceiveProps(nextProps) {}

  //编辑状态初始化币种金额
  initAmount = () => {
    const { isEditBudget, itinerary, budgetId } = this.props.params;
    if (isEditBudget) {
      itinerary.itineraryBudgetDTOList && itinerary.itineraryBudgetDTOList.forEach(budget => {
        if (budget.applicationCustomBudgetId === budgetId) {
          this.setState({currencyCode: budget.currencyCode, amount: budget.amount});
        }
      });
    }
  };

  //处理表单控件
  initFields = () => {
    const { customFormFields } = this.props;
    const { isEditBudget } = this.props.params;
    let fields = JSON.parse(JSON.stringify(customFormFields));
    this.processRangeDate(fields, true);//处理套件下的日期连选
    this.processRangeDate(fields, false);//处理非套件的日期连选
    if (isEditBudget) {
      //变更后，原行程下的套件内的子组件不可编辑
      this.processDisabled(fields);
    }
    //处理控件默认值, 日期连选的默认值在上面两个方法中处理
    !isEditBudget && this.processCityCombine(fields); //处理套件下的地点控件的默认值 新建明细时处理，编辑明细无需处理
    this.processInitCurrency(fields); //新建时处理币种的默认值 编辑也要处理币种是否可编辑
    fields.sort((a, b) => a.sequence > b.sequence || -1);
    this.setState({customFormFields: fields});
  };

  processDisabled = (fields) => {
    const { itinerary, budgetId } = this.props.params;
    let isExtend = false;
    itinerary.itineraryBudgetDTOList && itinerary.itineraryBudgetDTOList.forEach(budget => {
      if (budget.applicationCustomBudgetId === budgetId) {
        isExtend = budget.isExtend;
      }
    });
    if (isExtend) {
      fields && fields.forEach(field => {
        if (field.widgetMessageKey) {
          field.isReadOnly = true;
        }
      });
    }
  };

  //处理日期连选
  //isCombine 是否处理套件的日期连选
  processRangeDate = (fields, isCombine) => {
    const { itinerary, expenseTypeOID, isEditBudget } = this.props.params;
    let startDateFieldName = '';
    let endDateFieldName = '';
    let startDateRequired = false;
    let endDateRequired = false;
    let widgetMessageKey = '';
    let sequence = null;
    let fieldOID = travelUtil.generateUid();

    fields && fields.forEach(field => {
      if (((isCombine && field.widgetMessageKey) || (!isCombine && !field.widgetMessageKey)) && field.messageKey === 'com_start_date') {
        startDateFieldName = field.fieldName;
        startDateRequired = field.required;
        widgetMessageKey = field.widgetMessageKey;
        sequence = field.sequence;
        if (isCombine && !isEditBudget) {
          field.value = moment(itinerary.startDate).hours(0).minutes(0).seconds(0).utc().format();
        }
      }
      if (((isCombine && field.widgetMessageKey) || (!isCombine && !field.widgetMessageKey)) && field.messageKey === 'com_end_date') {
        endDateFieldName = field.fieldName;
        endDateRequired = field.required;
        if (isCombine && !isEditBudget) {
          field.value = moment(itinerary.endDate).hours(0).minutes(0).seconds(0).utc().format();
        }
      }
      //火车套件下的日期赋值
      if (isCombine && !isEditBudget && field.widgetMessageKey && field.messageKey === 'com_date') {
        field.value = moment(itinerary.startDate).hours(0).minutes(0).seconds(0).utc().format();
      }
    });
    let rangePicker = {
      messageKey: 'com_range_picker',
      fieldOID,
      widgetMessageKey,
      sequence,
      frontID: `${itinerary.itineraryHeadId}|${expenseTypeOID}|${fieldOID}`,
      fieldName: `${startDateFieldName} - ${endDateFieldName}`,
      promptInfoList: [startDateFieldName, endDateFieldName],
      fieldType: 'TEXT',
      disabledDate: current => requestUtil.disabledDateByParam(current, itinerary.startDate, itinerary.endDate, isCombine),
      enableTime: false,
      defaultValueTime: [], //启用时间的默认值
      required: startDateRequired && endDateRequired,
      value: null
    };
    let hasStartEndDate = 0;
    let startDate = null;
    let endDate = null;
    let enableStartDateTime = false; //开始日期启用时间
    let enableEndDateTime = false; //结束日期启用时间
    fields && fields.forEach(field => {
      if (((isCombine && field.widgetMessageKey) || (!isCombine && !field.widgetMessageKey)) && field.messageKey === 'com_start_date') {
        enableStartDateTime = requestUtil.processEnableTime(field);
        rangePicker.defaultValueTime.push(requestUtil.processDefaultTime(field));
        hasStartEndDate++;
        startDate = field.value;
      }
      if (((isCombine && field.widgetMessageKey) || (!isCombine && !field.widgetMessageKey)) && field.messageKey === 'com_end_date') {
        enableEndDateTime = requestUtil.processEnableTime(field);
        rangePicker.defaultValueTime.push(requestUtil.processDefaultTime(field));
        hasStartEndDate++;
        endDate = field.value;
      }
    });
    if (hasStartEndDate === 2) {
      if (enableStartDateTime && enableEndDateTime) {
        rangePicker.enableTime = true;
      }
      if (isEditBudget) {
        rangePicker.showValue = [startDate, endDate];
      }
      // com_range_picker不直接在customFormFields赋默认值，因为moment对象无法深拷贝，为保证提交数据的时候能深拷贝出副本，这个控件的默认值额外处理
      // if (isCombine) {
      //   rangePicker.showValue = [moment(itinerary.startDate), moment(itinerary.endDate)];
      //   rangePicker.value = [moment(itinerary.startDate), moment(itinerary.endDate)];
      // }
      fields.push(rangePicker);
    }
  };

  processCityCombine = (fields) => {
    const { itinerary } = this.props.params;
    fields && fields.forEach(field => {
      if (['suite_flight', 'suite_train'].indexOf(field.widgetMessageKey) > -1 && field.messageKey === 'com_departure_city') {
        field.value = itinerary.fromCityCode;
        field.showValue = itinerary.fromCityName;
      }
      if (['suite_flight', 'suite_train'].indexOf(field.widgetMessageKey) > -1 && field.messageKey === 'com_arrival_city') {
        field.value = itinerary.toCityCode;
        field.showValue = itinerary.toCityName;
      }
      if (['suite_hotel', 'suite_dining'].indexOf(field.widgetMessageKey) > -1 && field.messageKey === 'com_city') {
        field.value = itinerary.toCityCode;
        field.showValue = itinerary.toCityName;
      }
    });
  };

  processInitCurrency = (fields) => {
    const { info, isEditBudget } = this.props.params;
    const { company } = this.props;
    let currencyCode = company.baseCurrency;
    let disabledCurrency = false;
    info.custFormValues && info.custFormValues.forEach(customValue => {
      if (customValue.messageKey === 'currency_code' && customValue.value) {
        currencyCode = customValue.value;
        disabledCurrency = true;
      }
    });
    fields && fields.forEach(field => {
      if (field.messageKey === 'com_budget') {
        if (!isEditBudget) {
          //新建初始化币种默认值
          field.value = JSON.stringify({currencyCode, amount: undefined});
          this.setState({currencyCode});
        }
        field.disabledCurrency = disabledCurrency;
      }
    });
  };

  //初始化是否有分摊
  initApportion = () => {
    const { expenseTypeList, expenseTypeOID, apportionParams, isEditBudget, itinerary, budgetId } = this.props.params;
    const { customFormFields } = this.props;
    let expense = requestUtil.getQuickExpense(expenseTypeOID, expenseTypeList);
    if (!isEditBudget && expense.apportionEnabled && customFormFields.filter(item => item.messageKey === 'com_budget').length > 0) {
      let apportionList = [JSON.parse(JSON.stringify(apportionParams.defaultApportion))];
      this.setState({isHasApportion: true, apportionList});
    }
    if (isEditBudget) {
      itinerary.itineraryBudgetDTOList && itinerary.itineraryBudgetDTOList.forEach(budget => {
        if (budget.applicationCustomBudgetId === budgetId && budget.apportionmentDTOList && budget.apportionmentDTOList.length) {
          this.setState({isHasApportion: true, apportionList: JSON.parse(JSON.stringify(budget.apportionmentDTOList))});
        }
      });
    }
  };

  initCopyValues = () => {
    let arr = [];
    arr.checkedChange = this.checkedChange;//设置监听
    arr.checkedOk = this.checkedOk;//设置监听 修改日期连选专用
    this.setState({copyValues: arr});
  };

  /**
   * 部分表单控件value值变化监听函数
   * @param field 表单项
   * @param value 控件value值（某一个对象的某一个属性值），
   * @param allValue 控件完整值（整个对象或者数组）
   */
  checkedChange = (field, value, allValue) => {
    const { itinerary } = this.props.params;
    const { isHasApportion } = this.state;
    //修改消费商，校验行程头城市是否在对应消费商下
    if (field.messageKey === 'com_prosumer' && value) {
      //消费商控件的value是supplierOID，allValue是消费商Obj
      let searchType = 'standard';
      let intEnable = true;
      if (allValue.function && allValue.function[0]) {
        searchType = allValue.function[0].locationVendorType;
        intEnable = allValue.function[0].intEnable;
      }
      let country = 'all';
      if (!intEnable) {
        country = 'china';
      }
      let extraParams = {};
      if (field.widgetMessageKey === 'suite_flight') {
        extraParams.businessType = 'isArea';
      }
      if (field.widgetMessageKey === 'suite_train') {
        extraParams.businessType = 'isTrain';
      }
      if (field.widgetMessageKey === 'suite_hotel') {
        extraParams.businessType = 'isHotel';
      }

      this.setState({loading: true});
      if (field.widgetMessageKey === 'suite_flight' || field.widgetMessageKey === 'suite_train') {
        Promise.all([
          travelService.isCityInVendor(searchType, itinerary.fromCityCode, country, extraParams),
          travelService.isCityInVendor(searchType, itinerary.toCityCode, country, extraParams)
        ]).then(res => {
          if (res[0].data && res[0].data.alias && res[1].data && res[1].data.alias) {
            this.setState({isConsumerErr: false});
          } else {
            this.setState({isConsumerErr: true});
          }
          this.setState({loading: false});
        }).catch(e => {
          this.setState({loading: false, isConsumerErr: true});
        });
      }
      if (field.widgetMessageKey === 'suite_hotel') {
        travelService.isCityInVendor(searchType, itinerary.toCityCode, country, extraParams).then(res => {
          if (res.data && res.data.alias) {
            this.setState({isConsumerErr: false});
          } else {
            this.setState({isConsumerErr: true});
          }
          this.setState({loading: false});
        }).catch(e => {
          this.setState({loading: false, isConsumerErr: true});
        });
      }
    }

    //修改com_budget上的金额，且费用类型开启了分摊，则要重新计算分摊金额和百分比，哦，改币种也要，币种影响金额的展示精度
    if (field.messageKey === 'com_budget') {
      if (Number(value.amount) >= 0 && value.amount !== '' && value.amount !== null) {
        this.setState({amount: Number(value.amount)});
      }
      if (value.currencyCode) {
        this.setState({currencyCode: value.currencyCode});
      }
      if (isHasApportion) {
        this.handleChangeAmountCurrency(value);
      }
    }
  };

  //日期连选控件打开或者关闭的时候的回调
  checkedOk = (field, value) => {
    let { customFormFields } = this.state;
    let startDate = null;
    let endDate = null;
    setTimeout(() => {
      //因为相比单据表单，不在componentWillReceiveProps实时更新field了，所以checkedOK中的field里的value不是最新的
      let newValue = this.props.form.getFieldValue(field.frontID);
      if (newValue) {
        field.value = JSON.stringify(newValue);
      }
      //value为false表示关闭日期弹框
      if (!value && field.value) {
        startDate = field.value.split('\"')[1];
        endDate = field.value.split('\"')[3];
        if (field.enableTime) {
          startDate = moment(startDate).second(0).utc().format();
          endDate = moment(endDate).second(0).utc().format();
        } else {
          startDate = moment(startDate).hours(0).minutes(0).seconds(0).utc().format();
          endDate = moment(endDate).hours(0).minutes(0).seconds(0).utc().format();
        }

        //赋值到com_start_date, com_end_date控件
        this.refreshRangeDate(customFormFields, startDate, endDate, !!field.widgetMessageKey);
        this.setState({customFormFields});
      }
    }, 500);
  };

  //连选日期变更后刷新date数据
  refreshRangeDate = (values, startDate, endDate, isCombine) => {
    values.forEach(res => {
      if(((isCombine && res.widgetMessageKey) || (!isCombine && !res.widgetMessageKey)) && res.messageKey === 'com_start_date'){
        res.value = startDate;
      }
      if(((isCombine && res.widgetMessageKey) || (!isCombine && !res.widgetMessageKey)) && res.messageKey === 'com_end_date'){
        res.value = endDate;
      }
    });
  };

  //分摊相关方法 -- start --
  //修改币种金额
  handleChangeAmountCurrency = (value) => {
    let { apportionList } = this.state;
    //按照比例重新计算分摊金额
    let amount = value.amount || 0;
    let expenseCurrencyCode = value.currencyCode;
    apportionList.forEach((oneApportion, index) => {
      //默认分摊另外处理
      if (index !== 0) {
        oneApportion.amount = Number((amount * oneApportion.scale / 100).toFixed(queryCurrencyPrecision(expenseCurrencyCode)));
        amount -= oneApportion.amount;
      }
    });
    apportionList[0].amount = Number(Number(amount).toFixed(queryCurrencyPrecision(expenseCurrencyCode)));
    this.setState({apportionList});
  };

  processColumns = (currencyCode) => {
    const { user, newProfile } = this.props;
    const { expenseTypeOID, jobInfo, apportionParams } = this.props.params;
    const { companyOID, departmentOID } = apportionParams;
    let expenseApportionColumns = [
      {title: messages('request-1.key277')/*分摊项*/, dataIndex: 'costCenterItems', render: (value, record, tableIndex) => {
        let lineDepartmentOID = ''; //分摊行上部门
        let parentCostCenterOID = ''; //父成本中心项oid
        value && value.map(item => {
          if (item.type === 1) {
            lineDepartmentOID = item.costCenterOID;
          }
          if (item.type === 0 && item.costCenterType === 'father') {
            parentCostCenterOID = item.costCenterOID;
          }
        });
        return (
          <div>
            {record.budgetLabelCode === 'BUD_002' && <Tag color="red">{messages('request-1.key278')/*超预算*/}</Tag>}
            {record.budgetLabelCode === 'BUD_003' && <Tag color="blue">{messages('request-1.key279')/*预算预警*/}</Tag>}
            {
              value.map((oneApportion, index) => {
                let chooserItem = null;
                let leafEnable = !React.Component.prototype.checkFunctionProfiles('department.leaf.selection.required', [undefined, false]);
                //部门
                if (oneApportion.type === 1) {
                  chooserItem = deepFullCopy(chooserData['department']);
                  chooserItem.url += `?leafEnable=${leafEnable}`;
                  if (newProfile && newProfile['department'] && newProfile['department']['fullPathDisabled'] === 'true') {
                    oneApportion.value = oneApportion.name ? [{name: oneApportion.name, departmentOid: oneApportion.costCenterOID}] : undefined;
                  } else {
                    oneApportion.value = oneApportion.name ? [{path: oneApportion.name, departmentOid: oneApportion.costCenterOID}] : undefined;
                  }
                  chooserItem.columns.map(item => {
                    if (item.dataIndex === 'name') {
                      item.render = (value, record) => {
                        let departmentOID = jobInfo.departmentOID;
                        let message = '';
                        if ((!departmentOID && user.departmentOID === record.departmentOid) || (departmentOID && departmentOID === record.departmentOid)) {
                          message = messages('request-1.key294')/*(我的)*/;
                        }
                        if(newProfile && newProfile['department'] && newProfile['department']['fullPathDisabled'] !== 'true'){
                          return (
                            <Popover
                              placement="topLeft"
                              content={`${message}${record.path}`}>
                              {message}{record.path}
                            </Popover>
                          );
                        }
                        return (
                          <Popover
                            placement="topLeft"
                            content={`${message}${record.name}`}>
                            {message}{record.name}
                          </Popover>
                        );
                      };
                    }
                  });
                }
                //成本中心
                if (oneApportion.type === 0) {
                  chooserItem = deepFullCopy(chooserData['cost_center_item']);
                  chooserItem.url = `${config.baseUrl}/api/my/cost/center/items`;
                  oneApportion.value = oneApportion.name ? [{name: oneApportion.name, costCenterItemOID: oneApportion.costCenterOID}] : undefined;
                }
                return (
                  <div key={index}>
                    {oneApportion.type === 1 && (
                      <Row type="flex" align="middle" style={{marginBottom: 5}}>
                        <Col span={6} className="expense-apportion-name">
                          <Popover content={oneApportion.fieldName}><span className="required" />{oneApportion.fieldName}</Popover>
                        </Col>
                        <Col span={18} className="expense-apportion-chooser">
                          <Chooser
                            selectorItem={chooserItem}
                            valueKey="departmentOid"
                            labelKey={(newProfile && newProfile['department'] && newProfile['department']['fullPathDisabled'] === 'true') ? 'name' : 'path'}
                            onlyNeed="departmentOid"
                            listExtraParams={{companyOID}}
                            value={oneApportion.value}
                            onChange={(e, all) => {
                              this.handleChangeApportionItem(e, all, tableIndex, oneApportion.type)
                            }}
                            single
                          />
                        </Col>
                      </Row>
                    )}
                    {oneApportion.type === 0 && (
                      <Row type="flex" align="middle" style={{marginBottom: 5}}>
                        <Col span={6} className="expense-apportion-name">
                          <Popover content={oneApportion.fieldName}>
                            {oneApportion.required && <span className="required" />}{oneApportion.fieldName}
                          </Popover>
                        </Col>
                        <Col span={18} className="expense-apportion-chooser">
                          <Chooser
                            selectorItem={chooserItem}
                            valueKey="costCenterItemOID"
                            labelKey="name"
                            onlyNeed="costCenterItemOID"
                            listExtraParams={{
                              costCenterOID: oneApportion.costCenter,
                              userOID: user.userOID,
                              companyOID,
                              departmentOID: lineDepartmentOID || departmentOID,
                              expenseTypeOID,
                              parentCostCenterItemOID: oneApportion.costCenterType === 'son' ? parentCostCenterOID : undefined
                            }}
                            value={oneApportion.value}
                            disabled={oneApportion.costCenterType === 'son' && !parentCostCenterOID}
                            onChange={(e, all) => {
                              this.handleChangeApportionItem(e, all, tableIndex, oneApportion.type, oneApportion.costCenter)
                            }}
                            single
                          />
                        </Col>
                      </Row>
                    )}
                  </div>
                )
              })
            }
          </div>
        );
      }},
      {title: messages('request-1.key280')/*分摊金额*/, dataIndex: 'amount', width: '15%', render: (value, record, tableIndex) => {
        return (
          <InputNumber
            size="small"
            min={0}
            precision={queryCurrencyPrecision(currencyCode)}
            step={1}
            disabled={tableIndex === 0}
            value={value}
            onChange={(num) => {this.handleChangeAmountOrScale(num, 'amount', tableIndex)}}
            placeholder={messages('common.please.input')/*请输入*/}
            style={{width:'100%'}}
          />
        )
      }},
      {title: messages('request-1.key281')/*分摊比例%*/, dataIndex: 'scale', width: '15%', render: (value, record, tableIndex) => {
        return (
          <InputNumber
            size="small"
            min={0}
            precision={2}
            step={1}
            disabled={tableIndex === 0}
            value={value}
            onChange={(num) => {this.handleChangeAmountOrScale(num, 'scale', tableIndex)}}
            placeholder={messages('common.please.input')/*请输入*/}
            style={{width:'100%'}}
          />
        )
      }},
      {title: messages('common.operation')/*操作*/, dataIndex: 'index', width: '15%', render: (value, record, tableIndex) => {
        return (
          <span>
            <a onClick={(e) => {e.stopPropagation(); this.copyApportion(tableIndex);}}>{messages('common.copy')/*复制*/}</a>&nbsp;&nbsp;&nbsp;
            {tableIndex !== 0 && (
              <a onClick={(e) => {e.stopPropagation(); this.deleteApportion(tableIndex);}}>{messages('common.delete')/*删除*/}</a>
            )}
          </span>
        )
      }}
    ];
    return expenseApportionColumns;
  };

  /**
   *
   * @param e valueOID
   * @param all valueItem
   * @param index 分摊行的序号
   * @param type 1部门 0成本中心
   * @param costCenter 成本中心OID
   */
  handleChangeApportionItem = (e, all, index, type, costCenter) => {
    const { newProfile, user } = this.props;
    const { jobInfo, apportionParams } = this.props.params;
    const { companyOID } = apportionParams;
    let { apportionList } = this.state;
    let isChangeDepartment = false;
    let isChangeFatherCostCenter = false;
    let parentCostCenterOID = '';
    apportionList[index].costCenterItems.forEach(costCenterItem => {
      //处理分摊中部门更改
      if (costCenterItem.type === type && type === 1 && e !== costCenterItem.costCenterOID) {
        isChangeDepartment = true;
        if (e) {
          costCenterItem.costCenterOID = all.departmentOid;
          costCenterItem.name = (newProfile && newProfile['department'] && newProfile['department']['fullPathDisabled'] === 'true') ? all.name :
            all.path ? all.path : all.name;
          costCenterItem.pathDepth = all.path ? all.path.split('|').length : costCenterItem.pathDepth ? costCenterItem.pathDepth : 1;
        } else {
          costCenterItem.costCenterOID = '';
          costCenterItem.name = '';
          costCenterItem.pathDepth = 1;
        }
      }
      //处理分摊中成本中心更改
      if (costCenterItem.type === type && type === 0 && costCenterItem.costCenter === costCenter && costCenter && e !== costCenterItem.costCenterOID) {
        if (e) {
          costCenterItem.costCenterOID = all.costCenterItemOID;
          costCenterItem.name = all.name;
        } else {
          costCenterItem.costCenterOID = '';
          costCenterItem.name = '';
        }
        if (costCenterItem.costCenterType === 'father') {
          isChangeFatherCostCenter = true;
          parentCostCenterOID = costCenterItem.costCenterOID;
        }
      }
    });
    if (isChangeFatherCostCenter) {
      apportionList[index].costCenterItems.forEach(costCenterItem => {
        //处理子成本中心的parentCostCenterOID & 清空子成本中心项
        if (costCenterItem.type === 0 && costCenterItem.costCenterType === 'son') {
          costCenterItem.parentCostCenterOID = parentCostCenterOID;
          costCenterItem.costCenterOID = '';
          costCenterItem.name = '';
        }
      });
    }
    if (isChangeDepartment) {
      this.setState({tableLoading: true});
      let params = {
        userOID: user.userOID,
        departmentOID: e || jobInfo.departmentOID,
        companyOID,
        costCenterItemOIDs: []
      };
      apportionList[index].costCenterItems.forEach(costCenterItem => {
        if (costCenterItem.type === 0 && costCenterItem.costCenterOID) {
          params.costCenterItemOIDs.push(costCenterItem.costCenterOID);
        }
      });
      requestService.checkCostCenterNeedEmptyV2(params).then(res => {
        //res.data中为false说明是不可见，要清空成本中心项
        if (res.data) {
          apportionList[index].costCenterItems.forEach(costCenterItem => {
            //清空成本中心项
            //costCenterItem.costCenterOID有值才需要清空，没值时res.data[costCenterItem.costCenterOID]是undefined，导致parentCostCenterOID置空了
            if (costCenterItem.type === 0 && !res.data[costCenterItem.costCenterOID] && costCenterItem.costCenterOID) {
              costCenterItem.costCenterOID = '';
              costCenterItem.name = '';
              if (costCenterItem.costCenterType === 'son' && costCenterItem.parentCostCenterOID && !res.data[costCenterItem.parentCostCenterOID]) {
                costCenterItem.parentCostCenterOID = '';
              }
            }
          });
        }
        this.setState({apportionList});
      }).finally(() => {
        this.setState({tableLoading: false});
      });
    } else {
      this.setState({apportionList});
    }
  };

  handleNewExpenseApportion = () => {
    eventTrack({
      category: '行程明细新建/编辑',
      action: '新建分摊'
    });
    const { apportionParams } = this.props.params;
    let { apportionList } = this.state;
    let apportionItem = JSON.parse(JSON.stringify(apportionParams.apportionTemplate));
    apportionList.push(apportionItem);
    this.setState({apportionList});
  };

  copyApportion = (tableIndex) => {
    eventTrack({
      category: '行程明细新建/编辑',
      action: '分摊复制'
    });
    let { apportionList } = this.state;
    let apportionItem = JSON.parse(JSON.stringify(apportionList[tableIndex]));
    apportionItem.amount = 0;
    apportionItem.scale = 0;
    apportionItem.defaultApportion = false;
    apportionItem.apportionmentOID = ''; //复制分摊行id要置空
    apportionItem.budgetCheckMessage = '';
    apportionItem.budgetLabelCode = '';
    apportionList.push(apportionItem);
    this.setState({apportionList});
  };

  deleteApportion = (tableIndex) => {
    eventTrack({
      category: '行程明细新建/编辑',
      action: '删除分摊'
    });
    const { currencyCode, amount } = this.state;
    let { apportionList } = this.state;
    apportionList.splice(tableIndex, 1);
    apportionList[0].amount = this.getDefaultAmountOrScale('amount', apportionList, amount, currencyCode);
    apportionList[0].scale = this.getDefaultAmountOrScale('scale', apportionList, amount, currencyCode);
    this.setState({apportionList});
  };

  /**
   *
   * @param value
   * @param type amount金额 scale比例
   * @param tableIndex 分摊行的序号
   */
  handleChangeAmountOrScale = (value, type, tableIndex) => {
    const { currencyCode, amount } = this.state;
    let { apportionList } = this.state;
    if (!isNaN(value) && value !== null && value !== undefined && value !== '' && amount !== 0 && amount !== null && amount !== '') {
      //修改金额
      if (type === 'amount') {
        let defaultAmount = amount;
        apportionList[tableIndex].amount = value;
        defaultAmount = this.getDefaultAmountOrScale('amount', apportionList, amount, currencyCode);
        if (defaultAmount < 0) {
          apportionList[tableIndex].amount = 0;
          //重算默认分摊的金额
          apportionList[0].amount = this.getDefaultAmountOrScale('amount', apportionList, amount, currencyCode);
        } else {
          apportionList[0].amount = defaultAmount;
        }
        //重算比例
        apportionList[tableIndex].scale = Number((apportionList[tableIndex].amount * 100 / amount).toFixed(2));
        apportionList[0].scale = this.getDefaultAmountOrScale('scale', apportionList, amount, currencyCode);
      }
      //修改比例
      if (type === 'scale') {
        let defaultScale = 100;
        apportionList[tableIndex].scale = value;
        defaultScale = this.getDefaultAmountOrScale('scale', apportionList, amount, currencyCode);
        if (defaultScale < 0) {
          apportionList[tableIndex].scale = 0;
          //重算默认分摊的比例
          apportionList[0].scale = this.getDefaultAmountOrScale('scale', apportionList, amount, currencyCode);
        } else {
          apportionList[0].scale = defaultScale;
        }
        //重算金额
        apportionList[tableIndex].amount = Number((amount * apportionList[tableIndex].scale / 100).toFixed(queryCurrencyPrecision(currencyCode)));
        apportionList[0].amount = this.getDefaultAmountOrScale('amount', apportionList, amount, currencyCode);
      }
      this.setState({apportionList});
    }
  };

  //计算默认分摊的金额或者比例
  /**
   *
   * @param type amount金额 scale比例
   * @param apportionList 分摊列表
   * @param amount 该费用类型的金额
   * @param currencyCode 该费用类型的币种
   */
  getDefaultAmountOrScale = (type, apportionList, amount, currencyCode) => {
    let defaultAmount = amount;
    let defaultScale = 100;
    apportionList && apportionList.forEach((oneApportion, index) => {
      if (index !== 0) {
        defaultAmount -= oneApportion.amount;
        defaultScale -= oneApportion.scale;
      }
    });
    if (type === 'amount') {
      return Number(defaultAmount.toFixed(queryCurrencyPrecision(currencyCode)));
    }
    if (type === 'scale') {
      return Number(defaultScale.toFixed(2));
    }
  };
  //分摊相关方法 -- end --

  //根据表单信息渲染控件
  renderCustom = (field) => {
    const { getFieldDecorator, getFieldsValue } = this.props.form;
    const { copyValues, isConsumerErr, budgetLoading, isHasAutoBudget, isBudgetErr } = this.state;
    const { jobInfo, suppliers, currencyOptions, itinerary, isEditBudget, formInfo, roomNum } = this.props.params;

    //label
    let label = field.fieldName;
    if (field.messageKey === 'com_number') {
      label = `${field.fieldName}${JSON.parse(field.fieldContent || '{}').unit ? `(${JSON.parse(field.fieldContent || '{}').unit})` : ''}`;
    }
    if (field.messageKey === 'com_prompt_text') {
      label = '';
    }

    //rules
    let maxLength = requestUtil.getMaxLength(field);
    let rules = [{
      required: field.required,
      message: messages('common.can.not.be.empty',{arg1: field.fieldName})/*{arg1} 不能为空*/
    }];
    maxLength && rules.push({
      max: maxLength,
      message: messages('common.max.characters.length',{arg1: maxLength})/*最多输入{arg1}个字符*/
    });

    field.messageKey === 'com_room_number' && rules.push({
      validator: (rule, value, callback) => {
        if (!value || value === 0) {
          callback(messages('request-1.key388')/*房间数不能为0，请联系管理员维护参与人性别*/);
        }
        callback();
      }
    });

    //控件默认值
    //默认值在加载customFormFields的时候塞在对应的field里了
    //直接用field，不能JSON转换，不然的话日期moment要重新处理
    //哈哈不能直接用field，不然提交数据的是否moment对象还是无法深拷贝
    let fieldDefaultValue = !isEditBudget ? JSON.parse(JSON.stringify(field)) : {};
    if (fieldDefaultValue.messageKey === 'com_range_picker' && fieldDefaultValue.widgetMessageKey) {
      fieldDefaultValue.showValue = [moment(itinerary.startDate), moment(itinerary.endDate)];
      fieldDefaultValue.value = [moment(itinerary.startDate), moment(itinerary.endDate)];
    }
    if (fieldDefaultValue.messageKey === 'com_room_number' && fieldDefaultValue.widgetMessageKey) {
      fieldDefaultValue.showValue = roomNum;
      fieldDefaultValue.value = roomNum;
    }

    return (
      <div key={field.frontID}>
        {/*展示连选日期时，不展示开始日期，结束日期*/}
        {/*套件下配置了不启用的控件，后台查表单的时候已经过滤掉了*/}
        {(field.messageKey !== 'com_start_date' && field.messageKey !== 'com_end_date') && requestUtil.isShowField(field, formInfo) && (
          <FormItem {...formItemLayout} label={label || ' '} key={field.frontID} colon={!!label}>
            {getFieldDecorator(field.frontID, {
              rules,
              valuePropName: field.messageKey === 'com_company_paid' ? 'checked' : 'value',
              initialValue: isEditBudget ? customField.getInitialValue(field) : customField.getDefaultValue(field, fieldDefaultValue) //没有从后台获取的defaultValue
            })(
              customField.renderForm({
                field,
                fieldDefaultValue: {},
                formDetail: {}, //这个在customField里是用于获取别的field的value值，这里form是原始数据，不会有新的value，如果有类似获取别的field的value需要额外处理
                copyValue: copyValues,
                formValues: getFieldsValue(),
                jobId: jobInfo.id,
                jobInfo,
                propsParams: {
                  departmentOID: jobInfo.departmentOID,
                  companyOID: jobInfo.companyOID,
                  suppliers,
                  currencyOptions,
                  originalFormInfo: formInfo
                },
                form: this.props.form,
                formKey: 'frontID' //这个key在customField里并未识别，只是用于计算公式控件，目前费用表单上不支持配这个控件
              })
            )}
            <If value={field.messageKey === 'com_prosumer' && isConsumerErr}>
              <div className="has-error">
                <div className="ant-form-explain">{messages('request-1.key389')/*此消费商不支持当前行程所选城市*/}</div>
              </div>
            </If>
            {field.messageKey === 'com_budget' && requestUtil.isShowBudgetRefresh(field, formInfo) && (
              <div>
                <If value={!budgetLoading}>
                  <span className={isBudgetErr ? 'form-icon-btn-err' : 'form-icon-btn'} onClick={() => this.refreshBudget(field.formWidgetMessageKey, field.frontID)}>
                    <Icon type="sync" />&nbsp;&nbsp;
                    {isHasAutoBudget && !isBudgetErr && messages('request-1.key821')/*刷新成功*/}
                    {isHasAutoBudget && isBudgetErr && messages('request-1.key822')/*刷新失败，请重新查询*/}
                    {!isHasAutoBudget && messages('request-1.key823')/*刷新*/}
                  </span>
                </If>
                <If value={budgetLoading}>
                  <span className="form-icon-btn-loading">
                    <Icon type="loading" />&nbsp;&nbsp;{messages('request-1.key824')/*刷新中*/}
                  </span>
                </If>
              </div>
            )}
          </FormItem>
        )}
      </div>
    )
  };

  //获取根据差标计算的预算金额和币种
  refreshBudget = (widgetMessageKey, frontID) => {
    eventTrack({
      category: '行程明细新建/编辑',
      action: '预算刷新'
    });
    const { info, itinerary } = this.props.params;
    const { customFormFields, isHasApportion } = this.state;
    let params = {
      applicationOID: info.applicationOID,
      itineraryHeadId: itinerary.itineraryHeadId,
      itineraryType: widgetMessageKey === 'suite_flight' ? 1001 : (widgetMessageKey === 'suite_train' ? 1002 : 1003)
    };
    if (widgetMessageKey === 'suite_hotel') {
      customFormFields.forEach(field => {
        if(field.widgetMessageKey && field.messageKey === 'com_start_date'){
          params.startDate = field.value;
        }
        if(field.widgetMessageKey && field.messageKey === 'com_end_date'){
          params.endDate = field.value;
        }
      });
    }
    this.setState({budgetLoading: true, isHasAutoBudget: true});
    requestService.getBudgetAmount(params).then(res => {
      this.setState({budgetLoading: false, isBudgetErr: false});
      this.setAmountAndCurrency(res.data.budgetAmount, res.data.baseCurrencyCode);
      this.props.form.setFieldsValue({[frontID]: {amount: res.data.budgetAmount, currencyCode: res.data.baseCurrencyCode}});
    }).catch(err => {
      errorMessage(err.response);
      this.setState({budgetLoading: false, isBudgetErr: true});
    });
  };

  //提供给父组件的调用方法 -- start --
  validateItemsValue = () => {
    const { apportionList, currencyCode, amount, isConsumerErr, customFormFields } = this.state;
    const { expenseTypeName } = this.props.params;
    let result = {};
    //校验预算控件
    if (!requestUtil.validateBudgetAmount(customFormFields, currencyCode, amount, expenseTypeName)) {
      result = {validateResult: false};
      return result;
    }
    //酒店套件日期同一天校验
    if (!requestUtil.validateHotelDate(customFormFields)) {
      result = {validateResult: false};
      return result;
    }
    this.props.form.validateFields((err, values) => {
      if (!err && !isConsumerErr) {
        if (requestUtil.validateApportion(apportionList)) {
          result = {
            validateResult: true,
            currencyCode,
            amount,
            apportionmentDTOList: apportionList,
            expenseBudgetCustomValueDTOs: this.getCustFormValues(values)
          };
        } else {
          result = {validateResult: false};
        }
      } else {
        result = {validateResult: false};
      }
    });
    return result;
  };

  getCustFormValues = (values) => {
    const { customFormFields } = this.state;
    let custFormValues = JSON.parse(JSON.stringify(customFormFields));
    custFormValues.map(item=> {
      Object.keys(values).map(key => {
        if (key === item.frontID) {
          item = customField.formatFormValue(item, values[key]);
        }
      })
    });

    let rangePickerLength = custFormValues.filter(item => item.messageKey === 'com_range_picker').length;
    let i = 0;
    for (i; i < rangePickerLength; i++) {
      //去除塞入的连选日期控件
      let rangePickerIndex = -1;
      custFormValues.forEach((item, index)=> {
        if (item.messageKey === 'com_range_picker') {
          rangePickerIndex = index;
        }
      });
      if (rangePickerIndex > -1) {
        custFormValues.splice(rangePickerIndex, 1);
      }
    }
    return custFormValues
  };

  setAmountAndCurrency = (amount, currencyCode) => {
    const { isHasApportion } = this.state;
    this.setState({amount: Number(amount), currencyCode: currencyCode});
    if (isHasApportion) {
      this.handleChangeAmountCurrency({amount: Number(amount), currencyCode: currencyCode});
    }
  };
  //提供给父组件的调用方法 -- end --

  render() {
    const { loading, isHasApportion, apportionList, currencyCode, tableLoading, customFormFields } = this.state;
    return (
      <div className="new-form itinerary-form">
        <Spin spinning={loading}>
          <Form>
            {customFormFields && customFormFields.map(field => {
              return this.renderCustom(field)
            })}
            <If value={isHasApportion}>
              <div className="expense-item">
                <Table
                  rowKey={(record, index) => index}
                  columns={this.processColumns(currencyCode)}
                  loading={tableLoading}
                  dataSource={apportionList}
                  pagination={false}
                  style={{width:'100%'}}
                  bordered
                  size="small"
                  footer={() => {return (
                    <span className="new-expense-apportion" onClick={this.handleNewExpenseApportion}>
                      <Icon type="plus"/>{messages('request-1.key305')/*新建分摊*/}
                    </span>
                  )}}
                />
              </div>
            </If>
          </Form>
        </Spin>
      </div>
    )
  }
}

RequestItineraryForm.propTypes = {
  customFormFields: React.PropTypes.array,
};

function mapStateToProps(state) {
  return {
    user: state.login.user,
    newProfile: state.login.options,
    company: state.login.company,
  }
}

const WrappedRequestItineraryForm = Form.create()(RequestItineraryForm);

export default connect(mapStateToProps)(WrappedRequestItineraryForm);
